package org.yinxue.swing.core.panel;


import fun.codedesign.yinxue.util.FileUtil;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;

/**
 * 文本+滚动条
 *
 * @author zengjian
 * @create 2018-03-28 11:06
 * @since 1.0.0
 */
public class YxTextArea extends JScrollPane {

    private JTextArea textArea = new JTextArea();

    public JPopupMenu tipMenu;
    public JPopupMenu rightClickMenu;

    public Clipboard clipboard;

    public YxTextArea() {
        super(VERTICAL_SCROLLBAR_ALWAYS, HORIZONTAL_SCROLLBAR_AS_NEEDED);
        textArea.setLineWrap(true);
        setViewportView(textArea);
        getVerticalScrollBar().setUnitIncrement(20);
        textArea.setFont(new Font("微软雅黑", Font.PLAIN, 20));

        tipMenu = new JPopupMenu();

        rightClickMenu = new JPopupMenu();

        clipboard = this.getToolkit().getSystemClipboard();

        JMenuItem copy = new JMenuItem("复制");
        JMenuItem cut = new JMenuItem("剪切");
        JMenuItem v = new JMenuItem("粘贴");
        copy.addActionListener(e -> {
            copy();
        });

        cut.addActionListener(e -> {
            cut();
        });

        v.addActionListener(e -> {
            v();
        });

        rightClickMenu.add(copy);
        rightClickMenu.add(cut);
        rightClickMenu.add(v);

        textArea.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int x = e.getX();
                int y = e.getY();
                if (e.getButton() == MouseEvent.BUTTON3) {
                    rightClickMenu.show(textArea, x, y);
                }
            }
        });



        textArea.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                String changeText = "";
                try {
                    changeText = e.getDocument().getText(e.getOffset(), e.getLength());
                } catch (BadLocationException ex) {
                    throw new RuntimeException(ex);
                }

                // 非全文加载时显示提示
                if (!(changeText.endsWith("\n"))) {
                    Rectangle rectangle = null;
                    try {
                        rectangle = textArea.modelToView(textArea.getCaretPosition());
                    } catch (BadLocationException ex) {
                        ex.printStackTrace();
                    }
                    if (rectangle!=null) {
                        tipMenu.removeAll();

//                        tipMenu.add(new JMenuItem())
                        tipMenu.show(textArea, (int) rectangle.getX(), (int) rectangle.getY() + rectangle.height);
                        tipMenu.setFocusable(false);

                    }
                }
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                System.out.println(e.toString());
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                System.out.println(e.toString());
            }
        });
        textArea.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {

            }

            @Override
            public void keyPressed(KeyEvent e) {
                System.out.println(e.toString());
                System.out.println("keyPressed" + e.toString());
                // CTRL+C  : https://blog.csdn.net/withiter/article/details/17247617
                if (e.getModifiers() == 2 && e.getKeyCode() == 67) {
                    copy();
                }
                // 注意：因为使用了系统的粘贴，这里不需要重复粘贴，否则会触发多次在输入框中粘贴
                // CTRL+V
//                if (e.getModifiers() == 2 && e.getKeyCode() == 86) {
//                    v();
//                }
                // CTRL + X
                if (e.getModifiers() == 2 && e.getKeyCode() == 88) {
                    cut();
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {

            }
        });
    }



    private void copy() {
        String tempText = textArea.getSelectedText();
        StringSelection editText = new StringSelection(tempText);
//        clipboard.setContents(null, null);
        clipboard.setContents(editText, editText);

//        new ClipboardOwner();
    }

    private void cut() {
        copy();
        int start = textArea.getSelectionStart();
        int end = textArea.getSelectionEnd();
        textArea.replaceRange("", start, end); //从Text1中删除被选取的文本。
    }

    private void v() {
        Transferable contents = clipboard.getContents(null);
        DataFlavor flavor = DataFlavor.stringFlavor;
        if (contents.isDataFlavorSupported(flavor)) {
            try {
                String str = (String) contents.getTransferData(flavor);
                textArea.insert(str, textArea.getCaretPosition());
//                        textArea.append(str);
                System.out.println(textArea.getText());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    public YxTextArea setText(String text) {
        textArea.setText(text);
        return this;
    }

    public String getText() {
        return textArea.getText();
    }

    public void append(String msg) {
        textArea.append(msg + "\n");
    }

    public void appendAndRefresh(String msg) {
        textArea.append(msg);
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }

    public JTextArea getTextArea() {
        return this.textArea;
    }

    /**
     * 刷新光标位置
     */
    public void refreshCaretPosition() {
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }

    public YxTextArea addYxKeyListener(KeyListener l) {
        textArea.addKeyListener(l);
        // 实现拖动文件至文本窗口显示  https://blog.csdn.net/java_faep/article/details/53523401
        textArea.setTransferHandler(new TransferHandler() {

            private static final long serialVersionUID = 1L;

            @Override
            public boolean importData(JComponent comp, Transferable t) {
                try {
                    Object o = t.getTransferData(DataFlavor.javaFileListFlavor);

                    String filepath = o.toString();
                    if (filepath.startsWith("[")) {
                        filepath = filepath.substring(1);
                    }
                    if (filepath.endsWith("]")) {
                        filepath = filepath.substring(0, filepath.length() - 1);
                    }
                    System.out.println(filepath);
                    textArea.setText(FileUtil.readText(new File(filepath)));
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return false;
            }

            @Override
            public boolean canImport(JComponent comp, DataFlavor[] flavors) {
                for (int i = 0; i < flavors.length; i++) {
                    if (DataFlavor.javaFileListFlavor.equals(flavors[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        return this;
    }


}
